package user_role_v1

import (
	"context"
	"errors"
	"gf-xb-api/internal/consts"
	"gf-xb-api/internal/dao"
	"gf-xb-api/internal/model/dto"
	"gf-xb-api/internal/model/entity"
	"gf-xb-api/utility/xpermission"
	"slices"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
)

func (s *sUserRole) Create(ctx context.Context, in *dto.CreateUserRoleInput) (err error) {

	// 参数检查
	if in == nil {
		return errors.New("参数不能为空")
	}

	if in.UserId == 0 || len(in.RoleIds) == 0 {
		return errors.New("参数不正确")
	}

	userId := in.UserId
	var user *entity.SysUser
	err = dao.SysUser.Ctx(ctx).WherePri(userId).Scan(&user)
	if err != nil {
		return err
	}

	if user == nil {
		return errors.New("用户不存在或者已被删除")
	}

	roleIds := in.RoleIds
	var roles []*entity.SysRole
	err = dao.SysRole.Ctx(ctx).WhereIn(dao.SysRole.Columns().Id, roleIds).Scan(&roles)
	if err != nil {
		return err
	}

	if len(roles) == 0 {
		return errors.New("角色不存在")
	}

	if len(roles) != len(roleIds) {
		return errors.New("部分角色不存在")
	}

	// validRoleIds := xslice.GetFieldSlice(roles, func(r *entity.SysRole) uint { return r.Id })

	cols := dao.SysUserRole.Columns()
	var userRoles []*entity.SysUserRole
	err = dao.SysUserRole.Ctx(ctx).Where(cols.UserId, userId).WhereIn(cols.RoleId, roleIds).Scan(&userRoles)
	if err != nil {
		return err
	}

	var activeRoleIds []uint
	var ignoreRoleIds []uint

	if len(userRoles) > 0 {
		// 被禁用的，启用; 启用中的，则忽略掉
		for _, ur := range userRoles {
			if ur.Status == uint(consts.STATUS_INACTIVE) {
				activeRoleIds = append(activeRoleIds, ur.RoleId)
			} else {
				ignoreRoleIds = append(ignoreRoleIds, ur.RoleId)
			}
		}
	}

	userUUID := xpermission.GetLoginUserUUID(ctx)

	var newUserRoles []entity.SysUserRole
	for _, roleId := range roleIds {
		if slices.Contains(ignoreRoleIds, roleId) || slices.Contains(activeRoleIds, roleId) {
			continue
		}

		newUserRoles = append(newUserRoles, entity.SysUserRole{
			UserId:    userId,
			RoleId:    roleId,
			Status:    uint(consts.STATUS_ACTIVE),
			CreatedBy: &userUUID,
			UpdatedBy: &userUUID,
		})
	}

	err = dao.SysUserRole.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {

		// 纯新增的
		if len(newUserRoles) > 0 {
			_, err := dao.SysUserRole.Ctx(ctx).Data(newUserRoles).Insert()
			if err != nil {
				return err
			}
		}

		// 重新启用的
		if len(activeRoleIds) > 0 {
			m := dao.SysUserRole.Ctx(ctx).Data(g.Map{
				cols.Status:    uint(consts.STATUS_ACTIVE),
				cols.UpdatedBy: userUUID,
			}).Where(cols.UserId, userId)

			if len(activeRoleIds) == 1 {
				m = m.Where(cols.RoleId, activeRoleIds[0])
			} else {
				m = m.WhereIn(cols.RoleId, activeRoleIds)
			}

			_, err = m.Update()
			if err != nil {
				return err
			}
		}

		return nil
	})

	return err
}
